package com.hopedove.data;

import android.text.TextUtils;

import androidx.annotation.NonNull;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Datetime {
    private static final Pattern regexCn = Pattern.compile("^([1-9]\\d{3})年(\\d{2})月(\\d{2})日 ([0-9][0-9])时([0-9][0-9])分([0-9][0-9])秒$");
    private static final Pattern regexCnShort = Pattern.compile("^([1-9]\\d{3})年(\\d{2})月(\\d{2})日$");
    private static final Pattern regexEn = Pattern.compile("^([1-9]\\d{3})-(\\d{2})-(\\d{2}) ([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$");
    private static final Pattern regexEnShort = Pattern.compile("^([1-9]\\d{3})-(\\d{2})-(\\d{2})$");

    final private static DateTimeFormatter dtfCnShort = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
    final private static DateTimeFormatter dtfCnLong = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
    final private static DateTimeFormatter dtfEnShort = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    final private static DateTimeFormatter dtfEnLong = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    final private LocalDateTime localDateTime;

    public Datetime(int year, int month, int dayOfMonth) {
        localDateTime = LocalDateTime.of(year, month, dayOfMonth, 0, 0, 0);
    }

    public Datetime(int year, int month, int dayOfMonth, int hour, int minute, int second) {
        localDateTime = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second);
    }

    public Datetime() {
        localDateTime = LocalDateTime.now();
    }

    public Datetime(@NonNull LocalDateTime ldt) {
        localDateTime = ldt;
    }

    public final LocalDateTime getLocalDateTime() {
        return localDateTime;
    }

    public final int year() {
        return localDateTime.getYear();
    }

    public final int month() {
        return localDateTime.getMonthValue();
    }

    public final int dayOfMonth() {
        return localDateTime.getDayOfMonth();
    }

    public final int hoursOfDay() {
        return localDateTime.getHour();
    }

    public final int minute() {
        return localDateTime.getMinute();
    }

    public final int second() {
        return localDateTime.getSecond();
    }


    public static Matcher matchesCnFormat(String content) {
        return regexCn.matcher(content);
    }

    public static Matcher matchesEnFormat(String content) {
        return regexEn.matcher(content);
    }

    public static boolean testCnFormatMatches(String content) {
        return matchesCnFormat(content).matches();
    }

    public static boolean testEnFormatMatches(String content) {
        return matchesEnFormat(content).matches();
    }

    public static Datetime parseDateString(String date) {
        if (TextUtils.isEmpty(date)) return null;
        final String text = date.trim();

        if (regexCn.matcher(text).matches()) {
            return parseCnFormat(text);
        } else if (regexEn.matcher(text).matches()) {
            return parseEnFormat(text);
        }
        return null;
    }

    public static Datetime parseCnFormat(String dateCn) {
        return parseFormat(dateCn, regexCn, regexCnShort);
    }

    public static Datetime parseEnFormat(String dateEn) {
        return parseFormat(dateEn, regexEn, regexEnShort);
    }

    private static Datetime parseFormat(String dateFormat, Pattern pattern, Pattern patternShort) {

        if (dateFormat != null) {
            final String content = dateFormat.trim();
            Matcher matcher = pattern.matcher(content);
            Matcher shortMatcher = patternShort.matcher(content);
            if (matcher.matches()) {
                int y = Integer.parseInt(matcher.group(1));
                int m = Integer.parseInt(matcher.group(2));
                int d = Integer.parseInt(matcher.group(3));
                int h = Integer.parseInt(matcher.group(4));
                int mm = Integer.parseInt(matcher.group(5));
                int s = Integer.parseInt(matcher.group(6));
                return new Datetime(y, m, d, h, mm, s);
            } else if (shortMatcher.matches()) {
                int y = Integer.parseInt(shortMatcher.group(1));
                int m = Integer.parseInt(shortMatcher.group(2));
                int d = Integer.parseInt(shortMatcher.group(3));
                return new Datetime(y, m, d, 0, 0, 0);
            }
        }
        return null;
    }


    public String dateFormatCn() {
        return localDateTime.format(dtfCnShort);
    }

    public String dateFormatEn() {
        return localDateTime.format(dtfEnShort);
    }

    public String dateTimeFormatCn() {
        return localDateTime.format(dtfCnLong);
    }

    public String dateTimeFormatEn() {
        return localDateTime.format(dtfEnLong);
    }

}
